"use strict";

/**
 * 校验是否为合法URL
 *
 * @since 1.1.0
 * @category 正则
 * @param {string} str 需要校验的字符串.
 * @param {object} config 配置参数.
 * @param {boolean} config.isDetail 是否返回详细信息, 为true时返回CheckResult, false时返回boolean 默认: false.
 *
 * @returns { boolean|CheckResult } 校验结果 或 结果对象.
 *
 * @typedef {object} CheckResult
 * @property {boolean} status 校验结果
 * @property {string} errorMsg 错误提示
 * @property {RexExp} reg 校验数据使用的RexExp对象
 *
 * @example
 *
 * z.isLegalURL('https://example.com/path?query=param')
 * // => true
 * z.isLegalURL('http://192.168.0.1')
 * // => true
 * z.isLegalURL('ftp://user:password@example.com')
 * // => true
 * z.isLegalURL('http://', { isDetail: true })
 * // { status: false, errorMsg: '格式错误!', reg: /^(https?|ftp):\/\/(([^:@]+:[^:@]+@)?(([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3})|(\[[0-9a-f:]{3,40}\])|(localhost))(\:\d+)?(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/i }
 *
 */
function isLegalURL(str) {
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
      _ref$isDetail = _ref.isDetail,
      isDetail = _ref$isDetail === void 0 ? false : _ref$isDetail;

  var rt = {
    status: false,
    errorMsg: ''
  };

  if (typeof str !== 'string') {
    throw new Error('类型错误');
  }

  var reg = '^((https?|ftp):)?(//)?' + // 匹配以http、https或ftp开头的URL
  '(([^:@]+:[^:@]+@)?' + // 匹配可选的用户名和密码，格式为username:password@，这部分是可选的
  '(([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // 匹配域名
  '((\\d{1,3}\\.){3}\\d{1,3})|' + // OR 匹配IPv4地址
  '(\\[[0-9a-f:]{3,40}\\])|' + // OR 匹配IPv6地址
  '(localhost))' + // OR 匹配localhost
  '(\\:\\d+)?' + // 匹配端口号，格式为:port。这部分是可选的
  "(\\/($|[a-zA-Z0-9\\u4e00-\\u9fa5.,?'\\\\+&%$#=~_-]+))*$"; // 匹配URL的路径部分，可以包含多个路径段，每个路径段以/开始

  rt.reg = new RegExp(reg, 'i');

  if (!rt.reg.test(str)) {
    rt.errorMsg = '格式错误!';
  } else {
    rt.status = true;
  }

  return isDetail ? rt : rt.status;
}

module.exports = isLegalURL;